package fun.stgoder.easydarwin.jobs.ctl.rest;

import fun.stgoder.easydarwin.jobs.bl.API;
import fun.stgoder.easydarwin.jobs.bl.BL;
import fun.stgoder.easydarwin.jobs.bl.model.api.Folders;
import fun.stgoder.easydarwin.jobs.bl.model.api.Player;
import fun.stgoder.easydarwin.jobs.bl.model.api.Pusher;
import fun.stgoder.easydarwin.jobs.comm.Code;
import fun.stgoder.easydarwin.jobs.comm.Constants;
import fun.stgoder.easydarwin.jobs.comm.model.Param;
import fun.stgoder.easydarwin.jobs.comm.model.Resp;
import fun.stgoder.easydarwin.jobs.comm.util.SqlUtil;
import fun.stgoder.easydarwin.jobs.comm.util.SqlUtil0;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.List;

@Api("streams api")
@RestController
@RequestMapping("/rest/stream")
public class StreamRest {

    @ApiOperation("get pushers")
    @GetMapping("/pushers")
    public Resp pushers() throws Exception {

        List<Pusher> pushers = API.pushers(0, 100, null, null, null).getRows();

        return new Resp(Code.REQUEST_OK, "succ", pushers);
    }

    @ApiOperation("get players")
    @GetMapping("/players")
    public Resp players() throws Exception {

        List<Player> players = API.players(0, 100, null, null, null).getRows();

        return new Resp(Code.REQUEST_OK, "succ", players);
    }

    @ApiOperation("get record folders")
    @GetMapping("/folders")
    public Resp folders() throws Exception {

        Folders folders = API.folders(0, 100, null, null, null);

        return new Resp(Code.REQUEST_OK, "succ", folders);
    }

    @ApiOperation("start a stream")
    @PostMapping("/start")
    public Resp start(@RequestParam("rtsp") @ApiParam(name = "rtsp", value = "rtsp addr", required = true) String rtsp,
                      @RequestParam("streamId") @ApiParam(name = "streamId", value = "custom stream id", required = true) String streamId,
                      @RequestParam(value = "transType", required = false) @ApiParam(name = "streamId", value = "custom stream id", required = false, defaultValue = "TCP", allowableValues = "TCP,UDP") String transType,
                      @RequestParam(value = "idleTimeout", required = false, defaultValue = "0") @ApiParam(name = "idleTimeout", value = "idel time out (ms)", required = false) int idleTimeout,
                      @RequestParam(value = "heartbeatInterval", required = false, defaultValue = "0") @ApiParam(name = "heartbeatInterval", value = "heart beat interval (ms)", required = false) int heartbeatInterval)
            throws Exception {

        if (StringUtils.isBlank(streamId))
            throw new Exception("streamId required");

        if (Constants.PRE_RECORD)
            streamId = "/" + streamId;

        String id = API.start(rtsp, streamId, transType, idleTimeout, heartbeatInterval);

        return new Resp(Code.REQUEST_OK, "succ", id);
    }

    @ApiOperation("stop a stream")
    @PostMapping("/stop/{streamId}")
    public Resp stop(
            @PathVariable("streamId") @ApiParam(name = "streamId", value = "custom stream id", required = true) String streamId)
            throws Exception {
        String content = null;
        if (Constants.PRE_RECORD) {
            String pusherId = API.getPusherIdByStreamId(streamId);
            if (pusherId != null) {
                content = API.stop(pusherId);
            } else {
                SqlUtil0.delete(
                        "delete from t_streams where custom_path = :custom_path",
                        new Param().add("custom_path", "/" + streamId));
            }
        } else {
            SqlUtil.delete("delete from stream where streamId = :streamId", new Param().add("streamId", streamId));
        }
        return new Resp(Code.REQUEST_OK, "succ", content);
    }

    @ApiOperation("server info (not available)")
    @GetMapping("/getserverinfo")
    public Resp getServerinfo() throws Exception {

        String serverinfo = API.getServerinfo();

        return new Resp(Code.REQUEST_OK, "succ", serverinfo);
    }

    @ApiOperation("get stream rtsp live path")
    @GetMapping("/rtsp/{streamId}")
    public Resp getRtspPath(
            @PathVariable("streamId") @ApiParam(name = "streamId", value = "custom stream id", required = true) String streamId) {
        return new Resp(Code.REQUEST_OK, "succ", "/" + streamId);
    }

    @ApiOperation("get stream http live path")
    @GetMapping("/http/{streamId}")
    public Resp getHttpPath(
            @PathVariable("streamId") @ApiParam(name = "streamId", value = "custom stream id", required = true) String streamId) {
        File currentWorkingM3u8Dir = BL.getCurrentWorkingM3u8Dir(streamId);
        return new Resp(Code.REQUEST_OK, "succ",
                "/record/" + streamId + "/" + currentWorkingM3u8Dir.getName() + "/out.m3u8");
    }

    @ApiOperation("get current working m3u8 dir")
    @GetMapping("/current-working-m3u8-dir/{streamId}")
    public Resp getCurrentWorkingM3u8Path(
            @PathVariable("streamId") @ApiParam(name = "streamId", value = "custom stream id", required = true) String streamId) {

        File currentWorkingM3u8Dir = BL.getCurrentWorkingM3u8Dir(streamId);

        return new Resp(Code.REQUEST_OK, "succ", currentWorkingM3u8Dir.getName());
    }
}
